package com.example.i.spy;

import java.util.Timer;
import java.util.TimerTask;

import android.R.string;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.provider.MediaStore;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity 
{

	// initialize game logic
	private static int RESULT_LOAD_IMAGE = 1;
	private static int RESULT_INITIATOR_INPUT = 2;
	private static int RESULT_HINTS_SCREEN = 3;
	private boolean setup = true;
	private int initiateX = 0;
	private int initiateY = 0;
	private int guessX = 0;
	private int guessY = 0;
	private boolean initiatorState = true;
	private boolean guessingState = false;
	private boolean player1 = true;
	private int score = 0;
	private String objectName;
	private String hint;
	private boolean hint2Clicked = false;
	private boolean hint3Clicked = false;

	// initialize player score and displays
	TextView player1DisplayScore;
	TextView player2DisplayScore;
	long player1Score = 0;
	long player2Score = 0;

	// initialize timer and current score displays
	TextView timerText;
	TextView scoreText;
	long startTime = 0;
	Timer timer = new Timer();
	private static final int INITIAL_SCORE = 1000;

	// initialize number of incorrect guesses, the incorrect guess penalty, and hint penalties
	private int incorrectGuesses = 0;
	private static final int TIME_PENALTY = 10;
	private static final int INCORRECT_GUESS_PENALTY = 100;
	private static final int HINT2_PENALTY = 100;
	private static final int HINT3_PENALTY = 100;

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		// inherit the constructor
		super.onCreate(savedInstanceState);
		// this locks the screen orientation so the picture does not "disappear"
		this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
		setContentView(R.layout.activity_main);

		// Implementing the timer text and start/stop button.
		timerText = (TextView)findViewById(R.id.timer);
		scoreText = (TextView)findViewById(R.id.score);

		// initialize the display for each player's score, and each player's name.
		player1DisplayScore = (TextView)findViewById(R.id.player1Score);
		player2DisplayScore = (TextView)findViewById(R.id.player2Score);
		TextView player1DisplayName = (TextView)findViewById(R.id.player1Name);
		TextView player2DisplayName = (TextView)findViewById(R.id.player2Name);
		player1DisplayScore.setText(String.valueOf(player1Score));
		player2DisplayScore.setText(String.valueOf(player2Score));
		// get the names of each player from the previous activity, and put them into the TextView.
		Bundle nameExtras = getIntent().getExtras();
		String player1Name = nameExtras.getString("playerName1");
		String player2Name = nameExtras.getString("playerName2");
		player1DisplayName.setText(String.valueOf(player1Name));
		player2DisplayName.setText(String.valueOf(player2Name));

		// setting up the start button for the initiator phase
		Button startButton = (Button)findViewById(R.id.start);
		startButton.setText("Start");
		startButton.setOnClickListener(new View.OnClickListener() 
		{
			public void onClick(View v) 
			{
				Button b = (Button)v;
				if(b.getText().equals("Pause"))
				{
					timer.cancel();
					timer.purge();
					b.setText("Start");
				}
				else
				{
					startTime = System.currentTimeMillis();
					timer = new Timer();
					timer.schedule(new timerTask(), 0,500);
					//b.setText("Pause");
					b.setVisibility(View.INVISIBLE);

					// make the image visible and start the guessing stage.
					ImageView imageView = (ImageView) findViewById(R.id.imgView);
					imageView.setVisibility(View.VISIBLE);

					Button hintButton = (Button)findViewById(R.id.hint_button);
					hintButton.setVisibility(View.VISIBLE);
					guessingState = true;
				}
			}
		});
		// set invisible for now.
		startButton.setVisibility(View.INVISIBLE);

		Button hintButton = (Button)findViewById(R.id.hint_button);
		hintButton.setVisibility(View.INVISIBLE);

		hintButton.setOnClickListener(new View.OnClickListener(){

			// @Override
			public void onClick(View arg0) {
				Intent i = new Intent(MainActivity.this, HintsScreen.class);
				i.putExtra("objectName", objectName);
				i.putExtra("hint", hint);
				i.putExtra("hint2Clicked", hint2Clicked);
				i.putExtra("hint3Clicked", hint3Clicked);
				startActivityForResult(i, RESULT_HINTS_SCREEN);
			}
		});

		// create the button for loading the picture at the start screen
		Button buttonLoadImage = (Button) findViewById(R.id.buttonLoadPicture);
		// have it listen for input
		buttonLoadImage.setOnClickListener(new View.OnClickListener(){

			// @Override
			public void onClick(View arg0) {

				// when the user does click on it, set the activity's intent, and go to the phone's media storage
				Intent i = new Intent(
						Intent.ACTION_PICK,
						android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
				// you finished the setup by loading a picture
				setup = false;
				// start the activity.
				startActivityForResult(i, RESULT_LOAD_IMAGE);
			}
		});
	}

	// This is the new activity that starts the gallery loading
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		// inherit its Activity constructor
		super.onActivityResult(requestCode, resultCode, data);

		// if it is a valid image...
		if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && data != null)
		{

			// get the data and put it in an Uri
			Uri selectedImage = data.getData();
			// save the filepath
			String[] filePathColumn = { MediaStore.Images.Media.DATA };

			// handle the cursor
			Cursor cursor = getContentResolver().query(selectedImage,
					filePathColumn, null, null, null);
			cursor.moveToFirst();

			// finish getting the correct filepath for the picture.
			int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
			String picturePath = cursor.getString(columnIndex);
			cursor.close();

			// view the image by going to the correct filepath
			ImageView imageView = (ImageView) findViewById(R.id.imgView);
			imageView.setImageBitmap(BitmapFactory.decodeFile(picturePath));
			imageView.setVisibility(View.VISIBLE);

			Context context = getApplicationContext();
			CharSequence text = "You are at the initiator stage. Pick an object!";
			int duration = Toast.LENGTH_SHORT;
			Toast toast = Toast.makeText(context, text, duration);
			toast.show();
		}

		// Activity results from the Initiator Input activity.
		else if (requestCode == RESULT_INITIATOR_INPUT && resultCode == RESULT_OK && data != null)
		{
			objectName = data.getStringExtra("objectName");
			hint = data.getStringExtra("hint");

			Context context = getApplicationContext();
			CharSequence text = "Initiator stage finished. Pass the phone to the first" +
					" guesser, and press the Start button when ready.";
			int duration = Toast.LENGTH_SHORT;
			Toast toast = Toast.makeText(context, text, duration);
			toast.show();

			// make the image invisible until guesser presses start.
			ImageView imageView = (ImageView) findViewById(R.id.imgView);
			imageView.setVisibility(View.INVISIBLE);

			Button b = (Button)findViewById(R.id.start);
			b.setVisibility(View.VISIBLE);

			Button buttonLoadImage = (Button) findViewById(R.id.buttonLoadPicture);
			buttonLoadImage.setVisibility(View.INVISIBLE);
		}

		// Activity results from the Hints Screen activity.
		else if (requestCode == RESULT_HINTS_SCREEN && resultCode == RESULT_OK && data != null)
		{
			hint2Clicked = data.getBooleanExtra("hint2Clicked", false);
			hint3Clicked = data.getBooleanExtra("hint3Clicked", false);	
		}
	}

	// This method listens every time the user touches the screen, and will be handling the guesses for the game.
	@Override
	public boolean onTouchEvent(MotionEvent event) 
	{
		if (event.getAction() == MotionEvent.ACTION_DOWN)
		{
			// make sure that they choose a spot that is on the picture.
			ImageView picture = (ImageView)findViewById(R.id.imgView);
			if ((event.getX() > picture.getRight() || event.getX() < picture.getLeft()))
			{
				return super.onTouchEvent(event);
			}
			// they chose a spot on the picture.
			else
			{
				// if you have the picture on the screen, and you are in the guessing state,
				// then get the coordinates that the guesser chose.
				if (!setup && guessingState)
				{
					guessX = (int)event.getX();
					guessY = (int)event.getY();
					// If the user's coordinates are correct, then display a win screen
					// Use a margin of error of 50 (pixels?) for the guesser, so they don't have to get the exact object.
					if (((initiateX - 50 <= guessX) && (guessX <= initiateX + 50)) && ((initiateY - 50 <= guessY) && (guessY <= initiateY + 50)))
					{

						// show the winning dialog
						Context context = getApplicationContext();
						CharSequence text = "You WIN!";
						int duration = Toast.LENGTH_SHORT;
						Toast toast = Toast.makeText(context, text, duration);
						toast.show();

						// and stop the timer
						Button b = (Button)findViewById(R.id.start);
						timer.cancel();
						timer.purge();
						b.setText("Start");
						b.setVisibility(View.INVISIBLE);

						Button buttonLoadImage = (Button) findViewById(R.id.buttonLoadPicture);
						buttonLoadImage.setVisibility(View.VISIBLE);

						Button hintButton = (Button)findViewById(R.id.hint_button);
						hintButton.setVisibility(View.INVISIBLE);

						// reset stats and award points
						incorrectGuesses = 0;
						hint2Clicked = false;
						hint3Clicked = false;
						setup = true;
						initiateX = 0;
						initiateY = 0;
						guessX = 0;
						guessY = 0;
						initiatorState = true;
						guessingState = false;

						// new resets
						objectName = "";
						hint = "";
						hint2Clicked = false;
						hint3Clicked = false;
						startTime = 0;

						// award points to the correct player
						if (player1)
						{
							player1Score += score;
						}
						else
						{
							player2Score += score;
						}
						//update the score fields
						player1DisplayScore.setText(String.valueOf(player1Score));
						player2DisplayScore.setText(String.valueOf(player2Score));
						// switch to the next player
						player1 = !player1;
						return true;
					}

					// otherwise they got it wrong, and points will be subtracted from their score.
					else 
					{
						incorrectGuesses++;
						// also tell them that they got it wrong
						Context context = getApplicationContext();
						CharSequence text = "Wrong! (-100 points)";
						int duration = Toast.LENGTH_SHORT;
						Toast toast = Toast.makeText(context, text, duration);
						// put the toast where the user touched the screen (the subtractions are the offset for the toast, as its
						// origin is the top left corner
						toast.setGravity(Gravity.TOP|Gravity.LEFT, guessX - 125, guessY - 80);
						toast.show();
						return true;
					}
				}

				// if you have the picture on the screen, and you are in the initiator state,
				// then get the coordinates that the user chose.
				else if (!setup && initiatorState)
				{
					initiateX = (int)event.getX();
					initiateY = (int)event.getY();
					initiatorState = false;

					Intent i = new Intent(this, InitiatorInput.class);
					i.putExtra("objectName", objectName);
					i.putExtra("hint", hint);
					startActivityForResult(i, RESULT_INITIATOR_INPUT);

					return true;
				}
			}
		}
		return super.onTouchEvent(event);
	}


	//this  posts a message to the main thread from our timerTask
	//and updates the timerText textfield
	@SuppressLint("NewApi")
	final Handler h = new Handler(new Callback()
	{
		public boolean handleMessage(Message msg)
		{
			long millis = System.currentTimeMillis() - startTime;
			int seconds = (int) (millis / 1000);
			int minutes = seconds / 60;
			seconds     = seconds % 60;

			timerText.setText(String.format("Time: %d:%02d", minutes, seconds));

			score = INITIAL_SCORE - seconds*TIME_PENALTY -
					incorrectGuesses*INCORRECT_GUESS_PENALTY;

			if(hint2Clicked == true)
				score = score - HINT2_PENALTY;

			if(hint3Clicked == true)
				score = score - HINT3_PENALTY;

			if(score <= 0)
			{
				score = 0;

				Button hintButton = (Button)findViewById(R.id.hint_button);
				hintButton.setVisibility(View.INVISIBLE);

				// show the losing dialog
				Context context = getApplicationContext();
				CharSequence text = "Time ran out!! 0 points awarded.";
				int duration = Toast.LENGTH_SHORT;
				Toast toast = Toast.makeText(context, text, duration);
				toast.show();

				// and stop the timer
				Button b = (Button)findViewById(R.id.start);
				timer.cancel();
				timer.purge();
				b.setText("Start");
				b.setVisibility(View.INVISIBLE);

				Button buttonLoadImage = (Button) findViewById(R.id.buttonLoadPicture);
				buttonLoadImage.setVisibility(View.VISIBLE);


				// reset stats and award points
				incorrectGuesses = 0;
				hint2Clicked = false;
				hint3Clicked = false;
				setup = true;
				initiateX = 0;
				initiateY = 0;
				guessX = 0;
				guessY = 0;
				initiatorState = true;
				guessingState = false;

				// new resets
				objectName = "";
				hint = "";
				hint2Clicked = false;
				hint3Clicked = false;
				startTime = 0;

				// switch to the next player
				player1 = !player1;
			}

			scoreText.setText(String.format("Score: %d", score));

			return false;
		}
	});
	//tells handler to send a message
	class timerTask extends TimerTask
	{
		@Override
		public void run()
		{
			h.sendEmptyMessage(0);
		}
	};
}
